/**
 * @a https://leetcode.cn/problems/number-of-1-bits/description/
 * @a https://leetcode.cn/problems/counting-bits/
 * @a https://leetcode.cn/problems/hamming-distance/description/
 * @a https://leetcode.cn/problems/single-number/
 * @a https://leetcode.cn/problems/single-number-iii/
 */

#include "common.h"

class Solution
{
public:
    int hammingWeight(int n)
    {
        int sum = 0;
        while (n)
        {
            n &= (n - 1);
            ++sum;
        }
        return sum;
    }
};

class Solution
{
public:
    vector<int> countBits(int n)
    {
        vector<int> ans(n + 1, 0);
        for (int i = 0; i <= n; ++i)
        {
            int tmp = i, cnt = 0;
            while (tmp)
            {
                tmp &= (tmp - 1);
                ++cnt;
            }
            ans[i] = cnt;
        }
        return ans;
    }
};

class Solution
{
public:
    int hammingDistance(int x, int y)
    {
        int z = x ^ y, cnt = 0;
        while (z)
        {
            z &= z - 1;
            cnt++;
        }
        return cnt;
    }
};

class Solution
{
public:
    int singleNumber(vector<int> &nums)
    {
        int singleton = 0; // a ^ 0 = a
        for (auto num : nums)
        {
            singleton ^= num;
        }
        return singleton;
    }
};
#define N 2
class Solution
{
public:
    int singleNumber(vector<int> &nums)
    {
        int ret = 0;
        for (int i = 0; i < 32; ++i)
        {
            int sum = 0;
            for (auto num : nums)
            {
                if (num & (1 << i))
                    ++sum;
            }
            sum %= N;
            if (sum == 1)
                ret |= (1 << i);
        }
        return ret;
    }
};


class Solution
{
public:
    vector<int> singleNumber(vector<int> &nums)
    {
        int mix_xor = 0;
        for (auto num : nums)
        {
            mix_xor ^= num;
        }
        int singleton1 = 0, singleton2 = 0;
        int mask = mix_xor == INT_MIN ? mix_xor : mix_xor & (-mix_xor);
        for (auto num : nums)
        {
            if (num & mask)
            {
                singleton1 ^= num;
            }
            else
            {
                singleton2 ^= num;
            }
        }
        return {singleton1, singleton2};
    }
};